import { reactive, ref, watch, ExtractPropTypes } from "vue";
import type { FormInstance, FormRules } from "element-plus";
import ajax from "@/util/request";
import {setupUpdateReturn} from "../setup";

/**
 * 获取提交表单数据
 * @param formData 
 * @returns 
 */
function getFormDataFun(formData: object):object {
    return { ...formData };
}

/**
 * 返回一个方法，调用后获取修改组件所需要用到的属性和方法
 * @param modelName 
 * @param props props对象，需要使用defineProps创建后传入
 * @param emits emits对象，需要使用defineEmits创建后传入
 * @param formRules 
 * @param insertURL 
 * @returns 
 */
function setupUpdate(
    { modelName,
        props,
        emits,
        formRules,
        queryRowURL,
        pk = `t_${modelName}_pk`,
        updateURL = `/${modelName}/update`,
        getFormData = getFormDataFun
    }: {
        modelName: string,
        props: Readonly<ExtractPropTypes<any>>,
        emits: (event: "close", ...args: any[]) => void,
        formRules?: FormRules,
        queryRowURL?: string,
        pk?: string
        updateURL?: string,
        getFormData?: (obj:any) => any
    }
): setupUpdateReturn {

    let updated:any = null;

    const myForm = ref<FormInstance>();
    const formData = reactive({});

    let rules;
    if (formRules) {
        rules = reactive<FormRules>(formRules);
    }


    /**
     * 重置表单
     * @param obj 重置的数据
     */
    function handleReset(obj: any) {
        updated = null;

        // 如果传递获取一行数据的URL，那么通过异步加载初始化表单数据
        if (queryRowURL) {
            const dataParam: any = {};
            dataParam[pk] = obj[pk];
            ajax({url:queryRowURL,data: dataParam}).then(
                ({ data }) => {
                    if (data.code > 0) {
                        Object.assign(formData, data.data);
                    }
                }
            );
            // 否则直接通过列表组件（父组件）传来的数据重置
        } else {
            Object.assign(formData, obj);
        }
    }

    watch(
        () => props.rowData,
        (newVal) => {
            if (!newVal) {
                return;
            }
            handleReset(newVal)
        },
        {
            immediate: true
        }
    );

    /**
     * 关闭组件
     */
    function handleClose() {
        emits("close", updated);
    }

    /**
     * 提交修改
     * @param myForm 修改表单
     */
    function handleUpdate(myForm: FormInstance) {
        myForm.validate((valid) => {
            if (!valid) {
                return;
            }
            const postData =  getFormData(formData)
            ajax({url:updateURL,data:postData}).then(({ data }) => {
                if (data.code > 0) {
                    alert({ type: "success", message: "修改成功" });

                    updated = postData;

                    // 关闭，并告知列表组件，有数据更新
                    handleClose();
                }
            });
        });
    }

    return {
        rules, myForm, formData, handleReset, handleClose, handleUpdate
    }
}

export default setupUpdate;